package com.ruoyi.web.utils;

import com.ruoyi.common.core.domain.R;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.web.vo.EmailInformationVO;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Properties;

/**
 */
@AllArgsConstructor
@Component
public class EmailUtil {

    private final ISysConfigService configService;

    /**
     * 发送邮件(替换参数)
     *
     * @param titleCode          <${参数名}，参数>  邮件标题替换参数集合
     * @param textContentCode    <${参数名}，参数>  内容邮件替换参数集合
     * @param email              收件人邮箱
     * @param emailInformationVO 邮件内容信息
     * @return
     */
    public R sendEmail(Map<String, String> titleCode, Map<String, String> textContentCode,
                       String email, EmailInformationVO emailInformationVO) {
        // 配置发送邮件的环境属性
        final Properties props = new Properties();
        // 发送邮件协议名称
        props.setProperty("mail.transport.protocol", configService.selectConfigByKey("MAIL_TRANSPORT_PROTOCOL"));
        // 表示SMTP发送邮件，发送服务器需要进行身份验证
        props.put("mail.smtp.auth",configService.selectConfigByKey("MAIL_SMTP_AUTH"));
        // 设置邮件服务器主机名
        props.put("mail.smtp.host",configService.selectConfigByKey("MAIL_SMTP_HOST"));
        //smtp登陆的账号、密码 ；需开启smtp登陆
        props.put("mail.user", configService.selectConfigByKey("MAIL_USER"));
        // 访问SMTP服务时需要提供的密码,不是邮箱登陆密码，一般都有独立smtp的登陆密码
        props.put("mail.password", configService.selectConfigByKey("MAIL_PASSWORD"));
        // 邮件SMTP时间限制,单位毫秒。这个是有关邮件读取时间长短。默认是无限制。
        props.put("mail.smtp.timeout", 30000);
        // 连接时间限制，单位毫秒。是关于与邮件服务器建立连接的时间长短的。默认是无限制
        props.put("mail.smtp.connectiontimeout", 30000);
        // 邮件发送时间限制，单位毫秒。看关发送邮件时内容上传的时间长短。默认同样是无限制。
        props.put("mail.smtp.writetimeout", 30000);
        // 阿里云25端口默认禁用，使用465 SSL接口
        props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.put("mail.smtp.port", "465");
        props.put("mail.smtp.socketFactory.port", "465");

        // 构建授权信息，用于进行SMTP进行身份验证
        Authenticator authenticator = new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                // 用户名、密码
                String userName = props.getProperty("mail.user");
                String password = props.getProperty("mail.password");
                return new PasswordAuthentication(userName, password);
            }
        };

        // 使用环境属性和授权信息，创建邮件会话
        Session mailSession = Session.getInstance(props, authenticator);
        // 创建邮件消息
        MimeMessage message = new MimeMessage(mailSession);

        try {
            // 设置发件人
            InternetAddress form = new InternetAddress(props.getProperty("mail.user"),
                    configService.selectConfigByKey("MAIL_SENDER"), "UTF-8");
            message.setFrom(form);

            // 设置收件人
            InternetAddress to = new InternetAddress(email);
            message.setRecipient(Message.RecipientType.TO, to);

            // 设置邮件标题
            String emailTitle = emailInformationVO.getTitle();
            if (titleCode != null && !titleCode.isEmpty()) {
                // 替换标题中的参数
                for (String title : titleCode.keySet()) {
                    emailTitle = emailTitle.replace(title,
                            titleCode.get(title) == null ? "" : titleCode.get(title));
                }
            }
            message.setSubject(emailTitle, StandardCharsets.UTF_8.name());
            // 设置邮件的内容体
            String emailTextContent = emailInformationVO.getTextContent();
            if (textContentCode != null && !textContentCode.isEmpty()) {
                // 替换内容中的参数
                for (String textContent : textContentCode.keySet()) {
                    emailTextContent = emailTextContent.replace(textContent,
                            textContentCode.get(textContent) == null ? "" : textContentCode.get(textContent));
                }
            }
            message.setContent(emailTextContent, "text/html;charset=UTF-8");
            // 发送邮件
            Transport.send(message);
        } catch (MessagingException | UnsupportedEncodingException e) {
            new RuntimeException(e);
        }
        return R.ok();
    }

}
